﻿using GamFi.API.Application.Contracts.Wallet.GetWalletInfo;
using GamFi.API.Application.Exceptions;
using GamFi.API.Application.Interfaces;
using GamFi.API.Application.Resources;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;

namespace GamFi.API.Application.Features.Queries.Wallet.GetWalletInfo;

/// <summary>
/// Обработчик для <see cref="GetWalletInfoQuery"/>
/// </summary>
public class GetWalletInfoQueryHandler(
    IDbContext dbContext,
    IUserContext userContext,
    IStringLocalizer<ExceptionMessages> localizer)
    : IRequestHandler<GetWalletInfoQuery, GetWalletInfoResponse>
{
    /// <inheritdoc />
    public async Task<GetWalletInfoResponse> Handle(GetWalletInfoQuery request, CancellationToken cancellationToken)
    {
        var wallet = await dbContext.Wallets
            .Include(w => w.Transactions)
            .Include(w => w.Purchases)
            .FirstOrDefaultAsync(w => w.UserId == userContext.CurrentUserId, cancellationToken);

        if (wallet is null)
            throw new WalletException(localizer[nameof(WalletException.WalletNotFound)]);

        var purchases = dbContext.Purchases.Include(p => p.Token);
        
        return new GetWalletInfoResponse
        {
            Balance = wallet.Balance,
            Transactions = wallet.Transactions?.Select(t => new GetWalletInfoTransactionResponse
                {
                    Id = t.Id,
                    Amount = t.Amount,
                    Date = t.Date,
                    Operation = t.Operation
                })
                .OrderByDescending(t => t.Date)
                .ToList() ?? [],
            Purchases = await purchases.Select(p => new GetWalletInfoPurchaseResponse
                {
                    Id = p.Id,
                    Amount = p.Amount,
                    Date = p.Date,
                    TokenId = p.TokenId,
                    TokenName = p.Token.Name
                })
                .OrderByDescending(p => p.Date)
                .ToListAsync(cancellationToken)
        };
    }
}